package me.yricky.mayu.ui.fasta

import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ContentPaste
import androidx.compose.material.icons.rounded.SaveAlt
import androidx.compose.material.icons.rounded.SettingsBackupRestore
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.yricky.mayu.desktop.AppState
import me.yricky.mayu.desktop.openDetail
import me.yricky.mayu.ui.GridItemButton
import me.yricky.mayu.ui.ItemTitleSp
import me.yricky.mayu.ui.LazyColumnWithScrollBar
import me.yricky.mayu.ui.horizontalSpacer
import me.yricky.mayu.utils.string
import java.awt.Dimension

/**
 * @author Yricky
 * @date 2022/4/17
 */

@Composable
fun FastaSeqModel.DetailContent(
    modifier: Modifier,
    mainContent:@Composable ColumnScope.(FastaSeqModel)->Unit = { it.SequenceGrid(Modifier.fillMaxWidth().weight(1f)) }
){
    Column(modifier = modifier) {
        SelectionContainer {
            Text(name, fontSize = ItemTitleSp, modifier = Modifier.padding(4.dp), maxLines = 1)
        }
        Row {
            Text("长度：${seq.size}")
        }
        Column(Modifier.fillMaxWidth(1f)) {
            ParserSelector()
            mainContent(this,this@DetailContent)
        }
    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun FastaSeqModel.DetailWindow(){
    Window({AppState.workList.removeIf { it.first == this }}, title = name){
        LaunchedEffect(Unit){
            window.minimumSize = Dimension(800,600)
        }
        DetailContent(Modifier.fillMaxSize()){
            var selectedTabIndex by remember { mutableStateOf(0) }
            TabRow(
                selectedTabIndex = selectedTabIndex,
                modifier = Modifier.fillMaxWidth(),
                backgroundColor = MaterialTheme.colors.background,
                contentColor = MaterialTheme.colors.primary){
                Tab(
                    selected = selectedTabIndex == 0,
                    onClick = { selectedTabIndex = 0 },
                    modifier = Modifier.weight(1f),
                    text = { Text("摘要") }
                )
                Tab(
                    selected = selectedTabIndex == 1,
                    onClick = { selectedTabIndex = 1 },
                    modifier = Modifier.weight(1f),
                    text = { Text("序列") }
                )
                Tab(
                    selected = selectedTabIndex == 2,
                    onClick = { selectedTabIndex = 2 },
                    modifier = Modifier.weight(1f),
                    text = { Text("操作") }
                )
            }
            Crossfade(selectedTabIndex){tabIndex ->
                when(tabIndex){
                    0->{ Abstract(Modifier.fillMaxWidth().weight(1f)) }
                    1->{
                        var subSeqRange by remember { mutableStateOf(IntRange(0,0)) }
                        val state:BottomDrawerState = rememberBottomDrawerState(BottomDrawerValue.Closed)
                        val scope = rememberCoroutineScope()
                        BottomDrawer(
                            drawerContent = {
                                Column(Modifier.fillMaxWidth().padding(8.dp), horizontalAlignment = Alignment.CenterHorizontally) {
                                    val subList  = seq.subList(subSeqRange.first,subSeqRange.last)
                                    Text("(${subSeqRange.first+1})${subList.firstOrNull()}..${subList.lastOrNull()}(${subSeqRange.last})")
                                    Row(Modifier.fillMaxWidth()) {
                                        val cbm = LocalClipboardManager.current
                                        NavigationRailItem(
                                            selected = false,
                                            onClick = {
                                                cbm.setText(AnnotatedString(subList.string()))
                                                scope.launch { state.close() }
                                            },
                                            icon = { Icon(Icons.Rounded.ContentPaste,"") },
                                            modifier = Modifier.weight(1f),
                                            label = { Text("复制") }
                                        )
                                    }
                                }
                            },
                            drawerState = state
                        ){
                            SequenceGrid(Modifier.fillMaxWidth().weight(1f)){
                                subSeqRange = it
                                scope.launch { state.expand() }
                            }
                        }
                    }
                    2->{
                        LazyVerticalGrid(GridCells.Adaptive(160.dp),Modifier.fillMaxWidth()){
                            item {
                                GridItemButton(
                                    { FastaSeqModel().also {
                                        it.name = "(Reversed)$name"
                                        it.seq.addAll(seq.asReversed())
                                        it.parser = parser
                                    }.openDetail() },
                                    Modifier.fillMaxWidth().height(160.dp),
                                    Icons.Rounded.SettingsBackupRestore
                                ){
                                    Text("反向序列")
                                }
                            }
                            item {
                                GridItemButton(
                                    {  },
                                    Modifier.fillMaxWidth().height(160.dp),
                                    Icons.Rounded.SaveAlt
                                ){
                                    Text("另存为")
                                }
                            }
                        }
                    }
                    else->{}
                }
            }

        }
    }
}

@Composable
fun FastaSeqModel.Abstract(modifier: Modifier = Modifier){
    var exactList by remember { mutableStateOf(emptyList<Pair<Char,Int>>()) }
    var otherList by remember { mutableStateOf(emptyList<Pair<Char,Int>>()) }
    LaunchedEffect(parser){
        withContext(Dispatchers.Default){
            val l1 = mutableMapOf<Char,Int>()
            val l2 = mutableMapOf<Char,Int>()
            seq.forEach {
                if(parser.isExact(it)){
                    l1[it] = (l1[it] ?: 0) + 1
                }else{
                    l2[it] = (l2[it] ?: 0) + 1
                }
            }
            exactList = l1.toList().sortedBy { -it.second }
            otherList = l2.toList().sortedBy { -it.second }
        }
    }
    LazyColumnWithScrollBar(
        modifier.padding(4.dp)
    ) {
        @Composable
        fun Pair<Char,Int>.RateRow(){
            Column(Modifier.padding(4.dp)) {
                val rate by animateFloatAsState(second.toFloat()/seq.size)
                Row(verticalAlignment = Alignment.CenterVertically) {
                    SeqChar(seq = this@Abstract,c = first)
                    Text("${parser.introOf(first)}${second}个，占比${String.format("%.1f",rate*100)}%", maxLines = 1)
                }
                LinearProgressIndicator(rate,Modifier.fillMaxWidth(), color = Color(parser.colorOf(first)))
            }
        }
        items(exactList) { it.RateRow() }
        item { Spacer(Modifier.horizontalSpacer().padding(16.dp)) }
        items(otherList) { it.RateRow() }
    }
}